package org.cloud.utils.http;

import com.alibaba.fastjson.JSON;
import okhttp3.*;
import org.cloud.utils.SystemStringUtil;
import org.cloud.utils.XmlUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class OKHttpClientUtil {

    Logger logger = LoggerFactory.getLogger(OKHttpClientUtil.class);

    private static final OKHttpClientUtil singleInstance = new OKHttpClientUtil();

    public static OKHttpClientUtil single() {
        return singleInstance;
    }

    private final OkHttpClient okHttpClient;

    private OKHttpClientUtil() {
        okHttpClient = OKHttpClientBuilder.single().buildOKHttpClient().build();
        okHttpClient.dispatcher().setMaxRequests(10000);
        okHttpClient.dispatcher().setMaxRequestsPerHost(5000);  //每台服务器最大5000个请求
    }


    public OkHttpClient getOkHttpClient() {
        return okHttpClient;
    }

    // 获取数据进行异步的call，针对get请求
    public Call createGetCall(HttpRequestParams httpRequestParams, String url) throws Exception {
        Request.Builder request = new Request.Builder();
        // 设置header头
        httpRequestParams.getHeaders().forEach((key, value) -> {
            if (value != null) {
                request.addHeader(key, value);
            }
        });
        HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
        httpRequestParams.getQueryParams().forEach((key, value) -> {
            if (key != null && value != null) {
                urlBuilder.addQueryParameter(key, value.toString());
            }
        });
        request.url(urlBuilder.build());
        return okHttpClient.newCall(request.build());
    }

    public Call createPostCall(HttpRequestParams httpRequestParams, String url) throws Exception {
        MediaType mediaTypeJSON = MediaType.parse("application/json; charset=utf-8");
        return createPostCall(httpRequestParams, url, mediaTypeJSON);
    }

    /**
     * 创建 POST 请求的异步 Call 对象
     *
     * @param httpRequestParams HTTP 请求参数
     * @param url               请求的 URL
     * @param mediaType         请求体的媒体类型
     * @return Call 异步请求对象
     * @throws Exception 如果创建请求时出错
     */
    public Call createPostCall(HttpRequestParams httpRequestParams, String url, MediaType mediaType) throws Exception {
        Request.Builder requestBuilder = new Request.Builder();

        // 设置请求头
        httpRequestParams.getHeaders().forEach((key, value) -> {
            if (value != null) {
                requestBuilder.addHeader(key, value);
            }
        });

        // 检查是否有请求体
        if (httpRequestParams.getRequestBody() == null || httpRequestParams.getRequestBody().isEmpty()) {
            // 没有 requestBody，使用 Form 表单格式提交查询参数
            FormBody.Builder formBodyBuilder = new FormBody.Builder();
            if (httpRequestParams.getQueryParams() != null) {
                httpRequestParams.getQueryParams().forEach((key, value) -> {
                    if (key != null && value != null) {
                        formBodyBuilder.add(key, value.toString());
                    }
                });
            }
            FormBody formBody = formBodyBuilder.build();
            requestBuilder.url(url).post(formBody);

        } else {
            // requestBody 不为空，添加 requestBody 到请求中
            HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();

            // 添加查询参数到 URL
            if (httpRequestParams.getQueryParams() != null) {
                httpRequestParams.getQueryParams().forEach((key, value) -> {
                    if (key != null && value != null) {
                        urlBuilder.addQueryParameter(key, value.toString());
                    }
                });
            }

            // 构建完整 URL
            requestBuilder.url(urlBuilder.build());

            // 确定 requestBody 的内容类型并生成请求体
            RequestBody requestBody;
            if (mediaType.type().equalsIgnoreCase("application") && mediaType.subtype().equalsIgnoreCase("xml")) {
                // 处理 XML 格式的请求体
                requestBody = RequestBody.create(XmlUtil.single().Object2XmlString(httpRequestParams.getRequestBody()), mediaType);
            } else {
                // 默认使用 JSON 格式的请求体
                requestBody = RequestBody.create(JSON.toJSONString(httpRequestParams.getRequestBody()), mediaType);
            }
            requestBuilder.post(requestBody);
        }

        // 创建请求
        return new OkHttpClient().newCall(requestBuilder.build());
    }
    // 同步请求GET请求
    public String getResponse(HttpRequestParams httpRequestParams, String url) throws Exception {
        ResponseBody body = createGetCall(httpRequestParams, url).execute().body();
        String result = body.string();
        body.close();
        return result;
    }

    // 同步发送POST请求
    public String postResponse(HttpRequestParams httpRequestParams, String url) throws Exception {
        ResponseBody body = createPostCall(httpRequestParams, url).execute().body();
        String result = body.string();
        body.close();
        return result;
    }

    public WebSocket connectionWebsocket(String url, WebSocketListener webSocketListener) {
        Request request = new Request.Builder().url(url).build();
        final WebSocket websocket = getOkHttpClient().newWebSocket(request, webSocketListener);
        getOkHttpClient().dispatcher().executorService().shutdown();
        return websocket;
    }
}
